home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / forms / FORMS / positioner.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  188 lines

  1. /*
  2.  * positioner.c
  3.  *
  4.  * Forms Object class: POSITIONER
  5.  *
  6.  * Written by: Mark Overmars
  7.  *
  8.  * Version 2.1 a
  9.  * Date: Nov  6, 1992
  10.  */
  11.  
  12. #include <malloc.h>
  13. #include "gl/gl.h"
  14. #include <sys/types.h>
  15. #include "forms.h"
  16.  
  17. /* The special information for positioners. */
  18. typedef struct {
  19.    float xmin, ymin;    /* minimal values */
  20.    float xmax, ymax;    /* maximal values */
  21.    float xval, yval;    /* current values */
  22.    float xstep, ystep;    /* step size to which values are rounded */
  23.    int always;          /* whether always returning value */
  24. } SPEC;
  25.  
  26. static float flinear(float val, float smin, float smax, float gmin, float gmax)
  27. /* performs linear interpolation */
  28. {
  29.   if (smin == smax) return gmax;
  30.   else return gmin + (gmax - gmin) * (val - smin) / (smax - smin);
  31. }
  32.  
  33. static void draw_positioner(FL_OBJECT *ob)
  34. /* Draws a positioner */
  35. {
  36.   SPEC *sp = ((SPEC *)(ob->spec));
  37.   float x1 = ob->x + FL_POSITIONER_BW + 1.0;
  38.   float y1 = ob->y + FL_POSITIONER_BW + 1.0;
  39.   float w1 = ob->w - 2.0 * FL_POSITIONER_BW - 2.0;
  40.   float h1 = ob->h - 2.0 * FL_POSITIONER_BW - 2.0;
  41.   float xx,yy;
  42.   xx = flinear(sp->xval, sp->xmin, sp->xmax,x1,x1+w1-1.0);
  43.   yy = flinear(sp->yval, sp->ymin, sp->ymax,y1,y1+h1-1.0);
  44.   fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,ob->col1,FL_POSITIONER_BW);
  45.   fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
  46.                         ob->lcol,ob->lsize,ob->lstyle,ob->label);
  47.   fl_line(x1,yy,w1,1.0,ob->col2);
  48.   fl_line(xx,y1,1.0,h1,ob->col2);
  49. }
  50.  
  51. static int handle_mouse(FL_OBJECT *ob,float mx,float my)
  52. /* Handle a mouse position change */
  53. {
  54.   SPEC *sp = ((SPEC *)(ob->spec));
  55.   float x1 = ob->x + FL_POSITIONER_BW + 1.0;
  56.   float y1 = ob->y + FL_POSITIONER_BW + 1.0;
  57.   float w1 = ob->w - 2.0 * FL_POSITIONER_BW - 2.0;
  58.   float h1 = ob->h - 2.0 * FL_POSITIONER_BW - 2.0;
  59.   float oldx = sp->xval, oldy = sp->yval;
  60.   sp->xval = flinear(mx, x1, x1+w1-1.0, sp->xmin, sp->xmax);
  61.   sp->yval = flinear(my, y1, y1+h1-1.0, sp->ymin, sp->ymax);
  62.   if (sp->xstep != 0.0) sp->xval = (int) (sp->xval/sp->xstep +0.5) * sp->xstep;
  63.   if (sp->ystep != 0.0) sp->yval = (int) (sp->yval/sp->ystep +0.5) * sp->ystep;
  64.   if (sp->xval < sp->xmin) sp->xval = sp->xmin;
  65.   if (sp->xval > sp->xmax) sp->xval = sp->xmax;
  66.   if (sp->yval < sp->ymin) sp->yval = sp->ymin;
  67.   if (sp->yval > sp->ymax) sp->yval = sp->ymax;
  68.   if (sp->xval != oldx || sp->yval != oldy)
  69.     { fl_redraw_object(ob); return 1; }
  70.   else
  71.     { return 0; }
  72. }
  73.  
  74. static int handle_positioner(FL_OBJECT *ob,int event,float mx,float my,char key)
  75. /* Handles an event */
  76. {
  77.   SPEC *sp = (SPEC *) ob->spec;
  78.   switch (event)
  79.   {
  80.     case FL_DRAW:
  81.     draw_positioner(ob);
  82.     return 0;
  83.     case FL_PUSH:
  84.     case FL_MOUSE:
  85.         return ( handle_mouse(ob,mx,my)  && sp->always);
  86.     case FL_RELEASE:
  87.         return (! sp->always);
  88.     case FL_FREEMEM:
  89.     free(ob->spec);
  90.     return 0;
  91.   }
  92.   return 0;
  93. }
  94.  
  95. /*------------------------------*/
  96.  
  97. FL_OBJECT *fl_create_positioner(int type,float x,float y,float w,float h,char label[])
  98. /* creates an object */
  99. {
  100.   FL_OBJECT *ob;
  101.   ob = fl_make_object(FL_POSITIONER,type,x,y,w,h,label,handle_positioner);
  102.   ob->boxtype = FL_POSITIONER_BOXTYPE;
  103.   ob->col1 = FL_POSITIONER_COL1;
  104.   ob->col2 = FL_POSITIONER_COL2;
  105.   ob->align = FL_POSITIONER_ALIGN;
  106.   ob->lcol = FL_POSITIONER_LCOL;
  107.  
  108.   ob->spec = (int *) fl_malloc(sizeof(SPEC));
  109.   ((SPEC *)(ob->spec))->xmin = 0.0;
  110.   ((SPEC *)(ob->spec))->xmax = 1.0;
  111.   ((SPEC *)(ob->spec))->xval = 0.5;
  112.   ((SPEC *)(ob->spec))->ymin = 0.0;
  113.   ((SPEC *)(ob->spec))->ymax = 1.0;
  114.   ((SPEC *)(ob->spec))->yval = 0.5;
  115.   ((SPEC *)(ob->spec))->xstep = 0.0;
  116.   ((SPEC *)(ob->spec))->ystep = 0.0;
  117.  
  118.   ((SPEC *)(ob->spec))->always = TRUE;
  119.  
  120.   return ob;
  121. }
  122.  
  123. FL_OBJECT *fl_add_positioner(int type,float x,float y,float w,float h,char label[])
  124. /* Adds an object */
  125. {
  126.   FL_OBJECT *ob;
  127.   ob = fl_create_positioner(type,x,y,w,h,label);
  128.   fl_add_object(fl_current_form,ob);
  129.   return ob;
  130. }
  131.  
  132. void fl_set_positioner_xvalue(FL_OBJECT *ob,float val)
  133. {
  134.   ((SPEC *)(ob->spec))->xval = val;
  135.   fl_redraw_object(ob);
  136. }
  137.  
  138. void fl_set_positioner_yvalue(FL_OBJECT *ob,float val)
  139. {
  140.   ((SPEC *)(ob->spec))->yval = val;
  141.   fl_redraw_object(ob);
  142. }
  143.  
  144. void fl_set_positioner_xbounds(FL_OBJECT *ob,float min,float max)
  145. {
  146.   ((SPEC *)(ob->spec))->xmin = min;
  147.   ((SPEC *)(ob->spec))->xmax = max;
  148.   fl_redraw_object(ob);
  149. }
  150.  
  151. void fl_set_positioner_ybounds(FL_OBJECT *ob,float min,float max)
  152. {
  153.   ((SPEC *)(ob->spec))->ymin = min;
  154.   ((SPEC *)(ob->spec))->ymax = max;
  155.   fl_redraw_object(ob);
  156. }
  157.  
  158. float fl_get_positioner_xvalue(FL_OBJECT *ob)
  159.   { return ((SPEC *)(ob->spec))->xval; }
  160.  
  161. float fl_get_positioner_yvalue(FL_OBJECT *ob)
  162.   { return ((SPEC *)(ob->spec))->yval; }
  163.  
  164. void fl_get_positioner_xbounds(FL_OBJECT *ob,float *min,float *max)
  165. {
  166.   *min = ((SPEC *)(ob->spec))->xmin;
  167.   *max = ((SPEC *)(ob->spec))->xmax;
  168. }
  169.  
  170. void fl_get_positioner_ybounds(FL_OBJECT *ob,float *min,float *max)
  171. {
  172.   *min = ((SPEC *)(ob->spec))->ymin;
  173.   *max = ((SPEC *)(ob->spec))->ymax;
  174. }
  175.  
  176. void fl_set_positioner_xstep(FL_OBJECT *ob, float value)
  177. /* Sets the step size to which values are rounded. */
  178.   { ((SPEC *)(ob->spec))->xstep = value; }
  179.  
  180. void fl_set_positioner_ystep(FL_OBJECT *ob, float value)
  181. /* Sets the step size to which values are rounded. */
  182.   { ((SPEC *)(ob->spec))->ystep = value; }
  183.  
  184. void fl_set_positioner_return(FL_OBJECT *ob, int value)
  185. /* Sets whether to return value all the time */
  186.   { ((SPEC *)(ob->spec))->always = value; }
  187.  
  188.